#include "Game.h"
#include "GameState.h"
#include "Screen.h"
#include "Timer.h"
#include "EventPoller.h"
#include <assert.h>


Game::Game() : m_appPaused(false)
{
	
}

void Game::Run()
{
	while(!m_appPaused)
	{
		Update();
		Draw();

		TheScreen::Instance()->Flip();
	}
}

void Game::Draw()
{
	m_pGameState->Draw();
}

void Game::Update()
{
	if(!m_appPaused)
	{
		TheTimer::Instance()->Update();
		TheEventPoller::Instance()->Update();
		m_pGameState->Update();
		
	}
}


void Game::SetGameState(GameState* theGameState)
{
	if (m_pGameState != theGameState)
	{
		if (m_pGameState)
		{
			m_pGameState->OnDeactivated();
		}

		m_pGameState = theGameState;
		m_pGameState->OnActivated();
	}
}


void Game::DrawGameObjects()
{
	std::map<int, GameObject*>::iterator it;
	it = m_objects.begin();
	for ( ; it != m_objects.end(); ++it)
	{
		it->second->Draw();
	}

}

void Game::UpdateGameObjects()
{
	std::map<int, GameObject*>::iterator it = m_objects.begin();
	std::map<int, GameObject*>::iterator end = m_objects.end();

	for ( ;	it != end; ++it)
	{
		it->second->Update();
	}
	if(m_objectsToDelete.size() != 0)
	{
		SafelyDeleteGameObjects();
	}
}

void Game::AddGameObject(int id, GameObject* g)
{
	assert(m_objects.find(id) == m_objects.end());
	m_objects[id] = g;
}

void Game::DeleteGameObject(int id)
{
	m_objectsToDelete.push_back(id);
	/*
	std::map<int, GameObject*>::iterator it = m_objects.find(id);
	assert(it->second);

	GameObject* go = it->second;
	//std::map<int, GameObject*>::iterator toDelete = it;
	m_objects.erase(it++);
	delete go;
	*/
	
}
void Game::SafelyDeleteGameObjects()
{
	std::vector<int>::iterator it = m_objectsToDelete.begin();
	std::vector<int>::iterator end = m_objectsToDelete.end();
	std::map<int, GameObject*>::iterator jt;

	for( ; it != end; ++it)
	{
		jt = m_objects.find(*it);
		assert(jt->second);

		GameObject* go = jt->second;
		std::map<int, GameObject*>::iterator toDelete = jt;
		jt++;
		//std::map<int, GameObject*>::iterator toDelete = it;
		m_objects.erase(toDelete);
		delete go;
	}
	m_objectsToDelete.clear();
}